/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.result;

import cn.hutool.core.bean.copier.BeanCopier;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjUtil;
import info.peigen.hotpot.common.core.annotation.Comment;
import info.peigen.hotpot.common.core.result.facade.DtoAble;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <b>(PageResult)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/5/21
 */
@SuppressWarnings("unchecked")
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class PageResult<T> extends ResultBase implements DtoAble {
    @ApiModelProperty(value = "当前页数", position = 1)
    @Comment("当前页数")
    int     page;
    @ApiModelProperty(value = "每页多少条", position = 2)
    @Comment("每页多少条")
    int     pageSize;
    @ApiModelProperty(value = "总条数", position = 3)
    @Comment("总条数")
    int     totalRow;
    @ApiModelProperty(value = "总页数", position = 4)
    @Comment("总页数")
    int     totalPage;
    @ApiModelProperty(value = "返回对象集合", position = 5)
    @Comment("返回对象集合")
    List<T> info;

    /** 计算总共有多少页 */
    protected void calcTotalPage() {
        if (totalRow == 0) {
            this.totalPage = 1;
        } else if (totalRow % this.pageSize == 0) {
            this.totalPage = totalRow / this.pageSize;
        } else {
            this.totalPage = totalRow / this.pageSize + 1;
        }
    }

    public <R> PageResult<R> convert(Function<? super T, ? extends R> mapper) {
        List<R> collect = this.getInfo()
                .stream()
                .map(mapper)
                .collect(Collectors.toList());
        PageResult page = this;
        page.setInfo(collect);
        return (PageResult<R>) page;
    }

    public void fromSuccess(List<T> infos) {
        setInfo(infos).setSuccessNotFee();
    }

    public void fromSuccess(PageResult<T> pageResult) {
        setInfo(pageResult.getInfo());
        setTotalPage(pageResult.getTotalPage());
        setTotalRow(pageResult.getTotalRow());
        setPageSize(pageResult.getPageSize());
        setPage(pageResult.getPage());
        setSuccessNotFee();
    }

    public ResultBase copyInfoTo(Object target, String... ignoreProperties) {
        if (target != null && !ObjUtil.isEmpty(this.getInfo())) {
            CopyOptions copyOptions = CopyOptions.create()
                    .setIgnoreNullValue(true)
                    .setIgnoreError(true)
                    .setIgnoreProperties(ignoreProperties);
            BeanCopier.create(this, target, copyOptions);
        }
        return this;
    }
}